<%@ page import="javax.jcr.Repository,
         org.apache.jackrabbit.j2ee.RepositoryAccessServlet,
         org.apache.jackrabbit.util.Text,
         javax.jcr.Session,
         javax.jcr.SimpleCredentials,
         javax.jcr.query.Query,
         javax.jcr.query.RowIterator,
         java.text.NumberFormat,
         javax.jcr.query.Row,
         javax.jcr.Node,
         java.net.URLEncoder,
         java.text.SimpleDateFormat,
         java.text.DateFormat,
         java.util.List,
         java.util.ArrayList,
         java.util.Iterator,
         javax.jcr.Value,
         javax.jcr.RepositoryException,
         org.apache.commons.fileupload.*,
         org.apache.commons.fileupload.servlet.*,
         org.apache.commons.fileupload.disk.*,
         java.io.*,
         java.util.zip.*,
         java.util.*,
         java.net.*,
         javax.mail.internet.*,
         javax.mail.*,
         java.util.*,
         org.apache.commons.io.IOUtils,
         java.net.*,
         org.ilookinto.jr.JCRStoreBean,
         org.ilookinto.util.NodeUtil,
         org.ilookinto.util.CloseUtil

         "
         %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">

<html>
  <body>
    <h1 align="center" > Upload File to Repository  </h1>
    <h4 align="center"> For multiple files -- zip them first and upload</h4>
    <div align="center">
      <form method="POST"  enctype="multipart/form-data">
        <input id="test"
               type="file" name="andy"/>

        <input type="submit" value="Upload"/>
      </form>
      <a href="viewsearch.jsp"> Goto Search Page </a>
    </div>

    <%
       //out.println("damn");
       //if (true)
       //return;
    %>

    <div align="center" id="statusId">  </div>
    <br/>
    <div align="center"> <span style="color:green"> File Uploaded Information </span> <br/>
      <%

          Session jcrSession = null;
          try {
            Repository rep;
            if (ServletFileUpload.isMultipartContent(request)) {

              try {
                rep = RepositoryAccessServlet.getRepository(pageContext.getServletContext());
                jcrSession = rep.login(new SimpleCredentials("admin", "admin".toCharArray()));
              } catch (Throwable e) {
      %>
      Error while accessing the repository: <font color="red"><%= Text.encodeIllegalXMLCharacters(e.getMessage())%></font><br>
      Check the configuration or use the <a href="admin/">easy setup</a> wizard.<%
                return;
              }

              // Create a factory for disk-based file items
              FileItemFactory factory = new DiskFileItemFactory();

              // Create a new file upload handler
              ServletFileUpload upload = new ServletFileUpload(factory);

              //Create a progress listener
              final HttpSession mysession = request.getSession(true);
              ProgressListener progressListener = new ProgressListener() {

                private long megaBytes = -1;

                public void update(long pBytesRead, long pContentLength, int pItems) {
                  long mBytes = pBytesRead / 100000;
                  if (pBytesRead == pContentLength) {
                    mysession.setAttribute("readed", pBytesRead + "");
                    mysession.setAttribute("length", pContentLength + "");
                  }
                  if (megaBytes == mBytes) {

                    return;
                  }
                  megaBytes = mBytes;
                  mysession.setAttribute("readed", pBytesRead + "");
                  mysession.setAttribute("length", pContentLength + "");
                  //System.out.println("We are currently reading item " + pItems);
                  if (pContentLength == -1) {
                    System.out.println("So far, " + pBytesRead + " bytes have been read.");

                  } else {
                    System.out.println("So far, " + pBytesRead + " of " + pContentLength
                            + " bytes have been read." + mysession.getAttribute("readed"));
                  }
                }
              };
              upload.setProgressListener(progressListener);

              java.util.List<FileItem> items = upload.parseRequest(request);
              Node root = jcrSession.getRootNode();


              Node folder = null; /*
              if (!root.hasNode("uploaded")) {
              folder = root.addNode("uploaded", "nt:folder");
              } else {
              folder = root.getNode("uploaded");
              }*/

              for (FileItem item : items) {
                String ct = item.getContentType();
                ct = ct.toLowerCase();
                org.apache.tika.mime.MimeTypes mt = new org.apache.tika.mime.MimeTypes();
                javax.activation.MimetypesFileTypeMap m = new javax.activation.MimetypesFileTypeMap();
                out.println("ContentType: " + ct + " <br/> FileName: " + item.getName() + "<br/>");
                if (!ct.isEmpty()) {
                  if (ct.contains("zip") && !ct.contains("gzip")) {
                    ZipInputStream zis = new ZipInputStream(item.getInputStream());
                    ZipEntry entry;
                    while ((entry = zis.getNextEntry()) != null) {
                      out.println("File Name: " + entry.getName() + "<br/>");

                      if (entry.isDirectory()) {
                        continue;
                      }
                      /*try {
                      Thread.currentThread().sleep(2000);
                      } catch(Exception e) {}*/
                      session.setAttribute("fileName", entry.getName());
                      Node file = fileNodeFromURL(entry.getName(), root);
                      out.println("Repository path: " + file.getPath());
                      if (file.hasNode("jcr:content")) {
                        file.getNode("jcr:content").remove();
                      }
                      Node resource = file.addNode("jcr:content", "nt:resource");

                      resource.setProperty("jcr:mimeType", mt.getMimeType(entry.getName()).getName());

                      if (entry.getSize() < SIZE) {
                        java.io.ByteArrayInputStream b = new ByteArrayInputStream(org.apache.commons.io.IOUtils.toByteArray(zis));
                        resource.setProperty("jcr:data", b);
                      } else {
                        File t1 = File.createTempFile("temp", null);
                        FileOutputStream fos = new FileOutputStream(t1);
                        org.apache.commons.io.IOUtils.copy(zis, fos);
                        fos.close();
                        FileInputStream fis = new FileInputStream(t1);
                        resource.setProperty("jcr:data", fis);
                        t1.delete();
                      }
                      java.util.Calendar lastModified = java.util.Calendar.getInstance();
                      lastModified.setTimeInMillis(entry.getTime());
                      resource.setProperty("jcr:lastModified", lastModified);
                      //out.println(entry.getName() + m.getContentType(entry.getName()));
                    }

                  } else if (item.getName().endsWith(".pst")) {


                    processPstFile(item, NodeUtil.emailNode("testing", root), session);
                  } else {

                    session.setAttribute("fileName", item.getName());
                    Node file = fileNodeFromURL(item.getName(), root);
                    out.println(file.getPath());
                    if (file.hasNode("jcr:content")) {
                      file.getNode("jcr:content").remove();
                    }
                    Node resource = file.addNode("jcr:content", "nt:resource");

                    resource.setProperty("jcr:mimeType", mt.getMimeType(item.getName()).getName());

                    resource.setProperty("jcr:data", item.getInputStream());
                    java.util.Calendar lastModified = java.util.Calendar.getInstance();
                    //lastModified.setTimeInMillis(item.);
                    //resource.setProperty("jcr:lastModified", lastModified);

                  }
                }
              }

              jcrSession.save();


            } else {
              //out.println("Nothing uploaded");
            }
          } catch (Exception e) {
            e.printStackTrace();
            if (jcrSession != null) {
              jcrSession.logout();
            }
          }

      %>
    </div>
  </body>
</html>

<%!  static final int SIZE = 1024 * 1024 * 10;

  public static Node fileNodeFromURL(String sUrl, Node root) throws Exception {
    // final URL currentURL = urls[i];
    // root.getNodes().hasNext() root.getNodes().nextR;

    String path = "";// urls[i].getPath();

    String host = "";
    if (!path.startsWith("http")) {
      path = sUrl;
    } else {
      URL url = new URL(sUrl);
      host = url.getHost();
    }
    List folderNames = new ArrayList();
    if (!host.isEmpty()) {
      folderNames.addAll(Arrays.asList(host.split("\\.")));
    }
    Collections.reverse(folderNames);
    if (!path.isEmpty()) {
      folderNames.addAll(Arrays.asList(path.split("/|\\\\")));
    }
    final String fileName = URLDecoder.decode((String) folderNames.remove(folderNames.size() - 1), "UTF-8").replaceAll(":", "_");
    System.out.println(folderNames);
    System.out.println(fileName);
    Node node = root;
    for (Iterator fn = folderNames.iterator(); fn.hasNext();) {
      String name = URLDecoder.decode((String) fn.next(), "UTF-8");
      name = name.replaceAll(":", "_");
      if (name.length() == 0) {
        continue;
      }
      if (!node.hasNode(name)) {
        node.addNode(name, "nt:folder");
        //System.out.println("added name=" + name);
      }
      node = node.getNode(name);
    }
    final Node file;
    if (!node.hasNode(fileName)) {
      file = node.addNode(fileName, "nt:file");
    } else {
      file = node.getNode(fileName);
    }
    return file;
  }

  //Logger log = Logger.getLogger("uploaded_jsp");
  void processPstFile(FileItem item, Node emailRootNode, HttpSession session) throws Exception {
    File tempPst = new File(System.getProperty("java.io.tmpdir"), new File(item.getName()).getName());
    OutputStream os =  new FileOutputStream(tempPst);
    IOUtils.copy(item.getInputStream(),os);
    os.close();
    item.getInputStream().close();
    Properties props = new Properties();
    // props.put("mail.from", "user2@mailserver.com");
    javax.mail.Session emailSession = javax.mail.Session.getInstance(props);
    final Store store = emailSession.getStore("imap");
    store.connect("localhost", "elookinto", "elookinto");
    String folderName = item.getName().substring(item.getName().lastIndexOf(File.separator) + 1, item.getName().lastIndexOf("."));

    Folder folder = null;
    try {

      folder = store.getDefaultFolder().getFolder(folderName);
      folder.delete(true);
    } catch (Exception e) {
    }
    String exePath = this.getServletContext().getRealPath("/") + "WEB-INF\\resources\\outlook\\pst2imap";
    ProcessBuilder pb = new ProcessBuilder(exePath, tempPst.getAbsolutePath());
    Process p = pb.start();
    final Scanner out = new Scanner(p.getInputStream());
    final Scanner error = new Scanner(p.getErrorStream());
    while (out.hasNextLine()) {
      System.out.println(out.nextLine());
    }
   // p.wait();
    folder = store.getDefaultFolder().getFolder("INBOX").getFolder(folderName);
    processMessage(folder, session, emailRootNode);
    store.close();
    folder.delete(true);

  }

  private void processMessage(Folder folder, javax.servlet.http.HttpSession session, Node emailRootNode) {
    if ("true".equals(session.getAttribute("cancel"))) {
      return;
    }

    try {
      JCRStoreBean jcrStoreBean = new JCRStoreBean();
      jcrStoreBean.setParentNode(emailRootNode);
      folder.open(Folder.READ_ONLY);
      // folder.getMessage(345);
      int count = folder.getMessageCount();
      for (int i = 1; i <= count; i++) {
        if ("true".equals(session.getAttribute("cancel"))) {
          session.setAttribute("mm", "process status: cancelled;" + folder.getFullName() + ";" + i + " of total " + folder.getMessageCount() + " processed <br/>");
          break;
        }
        try {
          Message m = folder.getMessage(i);
          jcrStoreBean.storeMessage(m);
          System.out.println(i + " " + m.getSubject());

          if (i % 10 == 0 || i == count) {
            session.setAttribute("mm", "process status:" + session.getAttribute("cancel") + ";" + folder.getFullName() + ";" + i + " of total " + folder.getMessageCount() + "<br/>" + m.getSubject());
          }

        } catch (Exception e) {
          e.printStackTrace();
          break;
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      CloseUtil.close(folder);
    }
    try {
      Folder list[] = folder.list();
      for (Folder f : list) {
        processMessage(f, session, emailRootNode);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
%>
